#include "IEC_asduEncoder.h"
#include <string.h>

using namespace XIEC;

xuint8 CAsduEncoder::encode(xuint8* dst, const DataUnitTag& dataUnit, const CVectInfoObject& infoObjects, const Settings &settings)
{
    if (dataUnit.vsq.cnt != infoObjects.size() || dataUnit.vsq.cnt == 0)
        return 0;
    xuint8 pos = 0;
    dst[pos++] = dataUnit.typeId;
    dst[pos++] = dataUnit.vsq.d;
    dst[pos++] = dataUnit.cot8[0];
    if (settings.cot_len != 1)
        dst[pos++] = dataUnit.cot8[1];
    dst[pos++] = dataUnit.ca8[0];
    if (settings.coa_len != 1)
        dst[pos++] = dataUnit.ca8[1];
    xuint8 infoAddrLen = settings.info_obj_addr_len;
    if (dataUnit.vsq.SQ) {
        for(CVectInfoObject::const_iterator it = infoObjects.begin(); it != infoObjects.end(); it++)
        {
            CInfoObject* info = *it;
            if (it == infoObjects.begin()) {
                if (pos + infoAddrLen > 250) {
                    return 0;
                }
                memcpy(dst+pos, info->addr().addr, infoAddrLen);
                pos += infoAddrLen;
            }
            if (pos + info->length() > 250) {
                return 0;
            }
            memcpy(dst+pos, info->data(), info->length());
            pos += info->length();
        }
    }
    else {
        for(CVectInfoObject::const_iterator it = infoObjects.begin(); it != infoObjects.end(); it++)
        {
            CInfoObject* info = *it;
            if (pos + info->length() + infoAddrLen > 250) {
                return 0;
            }
            memcpy(dst+pos, info->addr().addr, infoAddrLen);
            pos += infoAddrLen;
            memcpy(dst+pos, info->data(), info->length());
            pos += info->length();
        }
    }
    return pos;
}


xuint8 CAsduEncoder::encode(xuint8* dst, const DataUnitTag& dataUnit, CInfoObject& infoObject, const Settings &settings)
{
    if (dataUnit.vsq.cnt != 1)
        return 0;
    xuint8 pos = 0;
    dst[pos++] = dataUnit.typeId;
    dst[pos++] = dataUnit.vsq.d;
    dst[pos++] = dataUnit.cot8[0];
    if (settings.cot_len != 1)
        dst[pos++] = dataUnit.cot8[1];
    dst[pos++] = dataUnit.ca8[0];
    if (settings.coa_len != 1)
        dst[pos++] = dataUnit.ca8[1];
    xuint8 infoAddrLen = settings.info_obj_addr_len;
    if (pos + infoObject.length() + infoAddrLen > 250)
        return 0;
    memcpy(dst+pos, infoObject.const_addr().addr, infoAddrLen);
    pos += infoAddrLen;
    memcpy(dst+pos, infoObject.const_data(), infoObject.length());
    pos += infoObject.length();
    return pos;
}
